package com.adwyxx.type;

import java.lang.reflect.Method;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.List;

/**
 * 通配符表达式 {@link WildcardType}
 * WildcardType 接口方法：
 * 1. Type[] getUpperBounds(); 获得泛型表达式上边界，表达式中使用 ? extends XXX，如果没有设置上界则上界为Object(因为所有的类型都继承自Object)
 * 2. Type[] getLowerBounds(); 获得泛型表达式的下边界，表达式中使用 ? super  XXX，如果没有设置下界则下界为null(因为null可以赋值给所有的类型)
 *
 * @author Leo
 * @date 2024/8/22 14:04
 */
public class WildcardTypeDemo {

    public <T> void test(List< ? extends OutputStream > outputStreams,  // 设置类上界
                         List< ? super InputStream    > inputStreams,   // 设置类下界
                         List<Integer> list, InputStream inputStream) {
    }

    public static void main(String[] args) {
        try {
            // 获取WildcardTypeDemo类的所有方法
            Method[] declaredMethods = WildcardTypeDemo.class.getDeclaredMethods();
            for (Method method : declaredMethods) {
                System.out.println("------------- Method : " + method.getName()+" -------------");
                // 获取方法的所有参数类型，即:泛型参数
                Type[] genericParameterTypes = method.getGenericParameterTypes();
                for (Type type : genericParameterTypes) {
                    System.out.println("type: " + type.toString());
                    // 如果不是参数化类型则直接continue
                    if (!(type instanceof ParameterizedType)) {
                        continue;
                    }
                    // 将当前类型强转为参数化类型并获取实际参数（即含有通配符的泛型类型）
                    Type actualTypeArgument = ((ParameterizedType) type).getActualTypeArguments()[0];
                    // 输出其是否为通配符类型
                    System.out.println("type instanceof WildcardType: " + (actualTypeArgument instanceof WildcardType));
                    if (actualTypeArgument instanceof WildcardType) {
                        WildcardType wildcardType = (WildcardType) actualTypeArgument;
                        System.out.println("WildcardType -> "+wildcardType);

                        // 获取通配符表达式的下界，即: ? super XXX 中的 XXX
                        Type[] lowerBounds = wildcardType.getLowerBounds();
                        // 获取通配符表达式的上界，即: ? extends XXX 中的 XXX
                        Type[] upperBounds = wildcardType.getUpperBounds();

                        // 输出上边界与下边界
                        // 打印下届，如果没有设置下界则下界为null(因为null可以赋值给所有的类型)
                        System.out.println("+--- lowerBounds -> " + (lowerBounds.length>0 ? lowerBounds[0].getTypeName():"null"));
                        // 打印上届，如果没有设置下界则下界为Object(因为所有的类型都继承自Object)
                        System.out.println("+--- upperBounds -> " + (upperBounds.length>0 ? upperBounds[0].getTypeName():"java.lang.Object"));
                    }
                    System.out.println();
                }
                System.out.println();
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }
}
